#include "TransformOperationWidget.h"
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Tool.hxx>

TransformOperationWidget::TransformOperationWidget(modelSoft* myModelSoft, QWidget *parent)
	: myModelSoft(myModelSoft)
	, QWidget(parent)
	, ui(new Ui::TransformOperationWidgetClass())
{
	ui->setupUi(this);
	transformFeature = new TransformFeature();
	//设定变换特征初始参数
    transformFeature->setTransformId(myModelSoft->shapeTag++);
	transformFeature->setAngel(0.0);
	transformFeature->setTranslationVec(gp_Vec(0,0,0));
	transformFeature->setSubEdgeIndex(-1);
	transformFeature->setResultId(transformFeature->getTransformId());
	transformFeature->setShapeId(transformFeature->getTransformId());
	//设置平移旋转标志
	rotate = false;
	pan = false;
	//设置主窗口传递选择Pipeline标志
	myModelSoft->myView->getInteractorStyle()->setTransformOperation(true);
	myModelSoft->myView->getInteractorStyle()->setBrepOperation(true);
	createConnection();
}


TransformOperationWidget::~TransformOperationWidget()
{
	delete ui;
}

void TransformOperationWidget::receiveSelectedShape(const TopoDS_Shape& selectedShape, Handle(QIVtkSelectionPipeline) pipeline)
{
	const TopoDS_Edge& edgeShape = TopoDS::Edge(selectedShape);
	const TopoDS_Vertex& firstVertex = TopExp::FirstVertex(edgeShape);
	const TopoDS_Vertex& lastVertex = TopExp::LastVertex(edgeShape);
	/*TopAbs_Orientation edgeOrientation = edgeShape.Orientation();*/
	//查找选择边在父对象的索引值
		//映射容器，用于存储 TopoDS_Shape 对象的索引映射
	TopTools_IndexedMapOfShape M;
	//遍历 S 中的所有边	将边的索引添加到 M 中
	TopExp::MapShapes(pipeline->getShape(), TopAbs_EDGE, M);
	int count = M.Extent();
	while (count >= 0) {
		if (M.FindKey(count).IsEqual(selectedShape)) {
			transformFeature->setSubEdgeIndex(count);
			break;
		}
		count--;
	}
	rotateStart = BRep_Tool::Pnt(firstVertex);
	rotateEnd = BRep_Tool::Pnt(lastVertex);
	rotateReceive = true;
	//清除旋转轴
	myModelSoft->currSelector->clearSelectedShape();
	//选择结束
	if (targetReceive) {
		ui->confirm->setEnabled(true);
	}
	
}

void TransformOperationWidget::receiveShapePipeline(Handle(QIVtkSelectionPipeline) pipeline)
{
	if (!targetReceive) {
		m_selectedPipelineTarget = pipeline;
		int pipelineId = pipeline->GetShapeID();
		auto iter = myModelSoft->m_Features.find(pipelineId);
		if (iter == myModelSoft->m_Features.end()) {
			return;
		}
		BaseFeature* feature = iter->second;
		transformFeature->setTargetFeature(feature);
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,178,102)");
		targetReceive = true;
		if (rotateReceive) {
			ui->confirm->setEnabled(true);
		}
	}
}

void TransformOperationWidget::OnClickConfirm()
{
	//创建变换
	gp_Trsf transform;
	gp_Trsf rotationTrsf;
	gp_Trsf vecTrsf;
	// 判断旋转是否有效
	if (!(IsNearlyZero(ui->angel->value()) || (IsNearlyZero(rotateEnd.X() - rotateStart.X()) && IsNearlyZero(rotateEnd.Y() - rotateStart.Y()) && IsNearlyZero(rotateEnd.Z() - rotateStart.Z()))))
	{
		rotate = true;
		gp_Dir rotateDir((rotateEnd.X() - rotateStart.X()), (rotateEnd.Y() - rotateStart.Y()), (rotateEnd.Z() - rotateStart.Z()));
		gp_Ax1 rotationAxis(rotateStart, rotateDir);
		rotationTrsf.SetRotation(rotationAxis, ui->angel->value());
        transformFeature->setAngel(ui->angel->value());
	}
	// 判断平移是否有效
	if (!(IsNearlyZero(ui->pX->text().toDouble()) && IsNearlyZero(ui->pY->text().toDouble()) && IsNearlyZero(ui->pZ->text().toDouble())))
	{
		pan = true;

		// 计算平移向量
		gp_Vec translationVec(ui->pX->text().toDouble(), ui->pY->text().toDouble(), ui->pZ->text().toDouble());
		vecTrsf.SetTranslation(translationVec);
        transformFeature->setTranslationVec(translationVec);
	}
	if (!rotate && !pan) {
		std::cout << "transform is invalid" << std::endl;
		return;
	}
	else if (!rotate) {
		transform = vecTrsf;
		transformFeature->setTransformType(1);
	}
	else if (!pan) {
		transform = rotationTrsf;
		transformFeature->setTransformType(0);
	}
	else {
		transform = rotationTrsf * vecTrsf;
		transformFeature->setTransformType(2);
	}
	m_resultPipeline = myModelSoft->TransformActor(m_selectedPipelineTarget, transform, transformFeature->getResultId());

	QStandardItem* item1 = new QStandardItem(QString("变换-%1").arg(transformFeature->getTransformId()));
	int row = myModelSoft->ui->model->rowCount();
	item1->setEditable(false);
	myModelSoft->ui->model->setItem(row, 0, item1);
	QStandardItem* item2 = new QStandardItem(QString("隐藏"));
	item2->setCheckable(true);
	myModelSoft->ui->model->setItem(row, 1, item2);
	myModelSoft->m_Features.insert(std::pair<Standard_Integer, TransformFeature*>(transformFeature->getTransformId(), transformFeature));

	transformFeature->AddOperation(transformFeature);
	close();
}


void TransformOperationWidget::OnClickSelectRotationEdge()
{
	//选择旋转轴
	myModelSoft->changeSelector(SM_Edge);
	myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
	myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Edge);
	
}

void TransformOperationWidget::OnSelTarget()
{
	myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Solid);
	myModelSoft->changeSelector(SM_Solid);
	myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
}

void TransformOperationWidget::OnCancelSelTarget()
{
	if (!m_selectedPipelineTarget.IsNull())
	{
		myModelSoft->RemoveSelectedActor(m_selectedPipelineTarget);
		m_selectedPipelineTarget = nullptr;
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,255,255)");
		targetReceive = false;
	}
}

void TransformOperationWidget::createConnection()
{
	connect(myModelSoft->currShapeSelector, &OccShapeSelector::sentShapePipeline, this, &TransformOperationWidget::receiveShapePipeline);
	connect(myModelSoft->currEdgeSelector, &OccEdgeSelector::sentEdgeShape, this, &TransformOperationWidget::receiveSelectedShape);
	connect(ui->cancel, &QPushButton::clicked, this, &TransformOperationWidget::close);
	connect(ui->confirm, &QPushButton::clicked, this, &TransformOperationWidget::OnClickConfirm);
	connect(ui->rotationAxisButton, &QPushButton::clicked, this, &TransformOperationWidget::OnClickSelectRotationEdge);
	connect(ui->targetSelect_3, &QPushButton::clicked, this, &TransformOperationWidget::OnCancelSelTarget);
	connect(ui->targetSelect_4, &QPushButton::clicked, this, &TransformOperationWidget::OnSelTarget);

	
}

void TransformOperationWidget::closeEvent(QCloseEvent* event)
{
	// 清除已选择的Actor
	myModelSoft->myView->getInteractorStyle()->clearCurrSelector();
	myModelSoft->myView->getInteractorStyle()->setTransformOperation(false);
	
}
